<template>
  <div class="pagination">
    <button
      :class="{
        disabled: page.currentPage === 1,
      }"
      :disabled="page.currentPage === 1"
      @click="page.currentPage--"
    >
      &lt;
    </button>
    <button
      :class="{
        active: page.currentPage === 1,
      }"
      @click="setPage(1)"
    >
      1
    </button>
    <button v-show="startEnd.start > 2">...</button>
    <button
      v-show="totalPages !== 1"
      v-for="(item, index) in startEnd.end - startEnd.start + 1"
      :key="index"
      :class="{
        active: page.currentPage === item + startEnd.start - 1,
      }"
      @click="setPage(item + startEnd.start - 1)"
    >
      {{ item + startEnd.start - 1 }}
    </button>
    <button v-show="startEnd.end < totalPages - 1">...</button>
    <button
      v-show="totalPages !== 1"
      :class="{
        active: page.currentPage === totalPages,
      }"
      @click="setPage(totalPages)"
    >
      {{ totalPages }}
    </button>
    <button
      :class="{
        disabled: page.currentPage === totalPages,
      }"
      :disabled="page.currentPage === totalPages"
      @click="page.currentPage++"
    >
      &gt;
    </button>
    <select v-model="page.pageSize" @change="setPageSize">
      <option
        v-for="(pageSize, index) in pageSizes"
        :value="pageSize"
        :key="index"
        >每页展示{{ pageSize }}条</option
      >
    </select>
  </div>
</template>

<script>
export default {
  name: "Pagination",
  props: {
    // 中划线命名的属性，传递数据时，会自动转换小驼峰命名法
    //当前页
    "current-page": {
      type: Number,
      default: 5,
    },

    //每页条数
    "page-size": {
      type: Number,
      default: 5,
    },
    // 可以切换每页条数
    "page-sizes": {
      type: Array,
      // 数组默认值，必须写成函数形式
      default: () => [5, 10, 15, 20],
    },
    // 总条数
    total: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      page: {
        currentPage: this.currentPage,
        pageSize: this.pageSize,
      },
    };
  },
  methods: {
    setPage(pageNo) {
      this.page.currentPage = pageNo;
      this.$emit("setPage", pageNo);
    },
    setPageSize() {
      console.log("每页展示数量", this.page.pageSize);
      console.log("当前页码", this.page.currentPage);
      console.log("总页码", this.totalPages);
      if (this.page.currentPage > this.totalPages) {
        this.page.currentPage = this.totalPages;
      }
      this.$emit("setPageSize", this.page.pageSize, this.page.currentPage);
    },
  },
  computed: {
    // 总页数
    totalPages() {
      console.log("总条数", this.total / this.page.pageSize);
      return Math.ceil(this.total / this.page.pageSize);
    },

    startEnd() {
      /*
        分析：
          1 ... 3 4 [5] 6 7 ... 10
            开始：1
            结束：总页数 totalPages
            问题：中间显示什么？
            已知：
              当前页码：currentPage
            求：中间按钮的开始的值 和 结束的值
            会定义计算属性，来计算 开始的值start 和 结束的值end
        解决：
          - start = currentPage - 2
          - end = currentPage + 2
            end = start + 5 - 1 = start + 4
        问题1:
          1 [2] 3 4 5 6 ... 10
          按照之前的公式：start = 0  end = 4
          而实际start = 2  end = 6
          怎么办？
            解决：start不能小于2
            if (start < 2) {
              start = 2;
            }
            这样计算：start = 2  end = 6
        问题2:
          1 ... 5 6 7 8 [9] 10
          按照之前的公式：start = 7  end = 11
          而实际start = 5  end = 9
          怎么办？
            解决：end 不能大于 totalPages - 1

            if (end > totalPages - 1) {
              // 只修正了end的值，start还有问题
              end = totalPages - 1;
              start = end - 4
            }
          这样计算：start = 5  end = 9
        问题3:
          1 2 [3] 4
        问题4:
          [1]
      */
      const { currentPage } = this.page;
      const { totalPages } = this;

      if (totalPages <= 1) {
        return {
          start: 0,
          end: -1,
        };
      }

      if (this.totalPages <= 7) {
        return {
          start: 2,
          end: totalPages - 1,
        };
      }

      let start = currentPage - 2;
      // 中间页数最小值不能小于2 因为1是固定占用
      if (start < 2) {
        start = 2;
      }

      let end = start + 4;
      // 中间页数最大值不能超过总页数-1
      // 并把最小值改为最大页数-4
      if (end > totalPages - 1) {
        end = totalPages - 1;
        start = end - 4;
      }
      // if (start < 2) {
      //   start = 2;
      // }

      return {
        start,
        end,
      };
    },
  },
};
</script>

<style lang="less" scoped>
.pagination {
  display: flex;
  justify-content: center;
  button {
    outline: none;
    border: none;
    margin: 0 5px;
    width: 30px;
    height: 30px;
    background-color: #f4f4f5;
    color: #606266;
    border-radius: 2px;
    cursor: pointer;
    &.active {
      background-color: #409eff;
      color: #fff;
    }
  }
  .disabled {
    background-color: rgb(248, 248, 248);
    color: rgb(201, 201, 201);
    cursor: not-allowed;
  }
}
</style>
